using System;
using System.IO;
using Gtk;
using AtDevice;

namespace GtkControls
{
    [System.ComponentModel.Category("GtkControls")]
    [System.ComponentModel.ToolboxItem(true)]
    public partial class StatusWidget : Gtk.Bin
    {
        
        public StatusWidget()
        {
            this.Build();
            DeviceHandler.DeviceOpened += delegate(AtDevice.AtDevice dev)
            {
                dev.GetInterface<IHuaweiInterface>().FlowUpdated += FlowUpdated;
                dev.GetInterface<IHuaweiInterface>().ModeChanged += ModeChanged;
                this.networkindicatorwidget1.NetworkType = AtUtils.GetNetworkName(dev.GetGSMInterface().GetNetworkType());
                RefreshInformation();
            };
            FillEntries();
        }
        
        private void FillEntries()
        {
            devicePathEntry.Completion = new Gtk.EntryCompletion();
            devicePathEntry.Completion.Model = CreateCompletionModel();
            devicePathEntry.Completion.TextColumn = 0;
            devicePathEntry.Text = "/dev/ttyUSB2";
        }
        
        private TreeModel CreateCompletionModel()
        {
            ListStore store = new ListStore(typeof(string));
            try
            {
                foreach (var item in new DirectoryInfo("/dev/").GetFiles("tty*")) {
                    store.AppendValues(item.FullName);
                }
            }
            catch (IOException)
            {
            }
            return store;
        }
        
        private string GetNetworkStatus(IGSMInterface gsmI)
        {
            string status = gsmI.GetNetwork();
            if(gsmI.GetCellId() != null)
                status += "/" + gsmI.GetCellId();
            
            if(gsmI.IsRoamed())
                status += " (roaming)";
            
            return status;
        }
        
        private void RefreshInformation()
        {
            AtDevice.IGSMInterface gsmI = DeviceHandler.Get().GetGSMInterface();
            this.imeiEntry.Text = gsmI.GetIMEI();
            this.imsiEntry.Text = gsmI.GetIMSI();
            this.deviceEntry.Text = gsmI.GetManufacturer() + " " + gsmI.GetModel();
            this.revisionEntry.Text = gsmI.GetModelRevision();
            
            double signal = 0.0;
            try {
                signal = gsmI.GetSignal();
            } catch(Exception) { }
            
            this.networkindicatorwidget1.Signal = signal;
            this.networkindicatorwidget1.NetworkName = GetNetworkStatus(gsmI);
        }
        
        private void FlowUpdated(int uptime, int dlSpeed, int ulSpeed, long dlBytes, long ulBytes)
        {
            Gtk.Application.Invoke(delegate
            {
                TimeSpan time = new TimeSpan(0, 0, uptime);
                uptimeLabel.Text = String.Format("{0} d {1} h {2} min {3} sec",
                                                 time.Days, time.Hours,
                                                 time.Minutes, time.Seconds);
            });
        }
        
        private void ModeChanged(NetworkEnum network)
        {
            Gtk.Application.Invoke(delegate {
                this.networkindicatorwidget1.NetworkType = AtUtils.GetNetworkName(network);
            });
        }

        protected virtual void OnConnectButtonClicked (object sender, System.EventArgs e)
        {
            try {
                DeviceHandler.Connect(devicePathEntry.Text);
                connectButton.Sensitive = false;
            }
            catch(ApplicationException ex)
            {
                Console.WriteLine("Opening the device failed: {0}", ex.ToString());
                Gtk.Application.Invoke(delegate {
                    string message = String.Format("Couldn't connect to the device {0}", devicePathEntry.Text);
                    this.vbox1.PackEnd(new NotificationBar(MessageType.Error, message), false, true, 0);
                 });
            }
        }
    }
}
